package org.club.Controller;


import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.club.Service.ActivityService;
import org.club.common.model.dto.*;
import org.club.common.model.vo.*;
import org.club.common.model.entity.BusinessException;
import org.club.common.model.entity.ClubMemberInfo;
import org.club.common.util.ApiResponseMe;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.nio.charset.StandardCharsets;
import java.util.Map;


//活动发布
@RestController
@RequestMapping("/activities")
@Tag(name = "社团管理员", description = "管理活动发布等")
public class CommunityAdminController {
    @Autowired
    private ActivityService activityService;

    /**
     * 根据用户ID查询社团信息
     * 此方法通过GET请求接收用户ID作为参数，调用服务层方法查询相应的社团信息，并返回给客户端
     *
     * @param userId 用户ID，用于查询特定用户的社团信息
     * @return 返回包含社团信息的ApiResponseMe对象，表示查询结果
     */
    @GetMapping("/selectClubsTest/{userId}")
    public ApiResponseMe selectClubsTest(@PathVariable Long userId) {
        // 调用服务层方法查询社团信息
        CommunityDetailsVo clubsDetailVO = activityService.selectClubsTest(userId);
        // 如果查询成功，返回包含社团信息的成功响应
        return ApiResponseMe.success(clubsDetailVO);
    }



/**
 * 查询活动列表
 *
 * 本方法通过POST请求接收客户端发送的活动查询参数，然后调用服务层方法进行查询，
 * 最终将查询结果封装成ApiResponseMe对象返回给客户端
 *
 * @param activityQueryDTO 活动查询参数对象，包含查询活动所需的各类参数
 * @return 包含查询结果的ApiResponseMe对象，用于向客户端反馈查询结果
 */
@PostMapping("/search")
@Operation(summary = "查询活动列表", description = "查询活动列表")
public ApiResponseMe searchActivities(@RequestBody ActivityQueryDTO activityQueryDTO) {
    List<ActivitiesVO> activities = activityService.searchActivities(activityQueryDTO);
    return ApiResponseMe.success(activities);
}




    /**
     * 创建活动
     *
     * 该方法用于处理活动创建请求，包括活动信息的接收、处理和存储
     * 它接受一个文件和一个活动请求对象作为输入参数，用于活动的创建
     *
     * @param file 活动相关的文件，例如活动海报或证明文件
     * @param request 活动请求对象，包含活动的各种详细信息
     * @return 返回一个ApiResponseMe对象，表示活动创建的结果
     */
    @Operation(summary = "创建活动", description = "创建活动")
    @PostMapping("/create")
    public ApiResponseMe createActivity(@RequestPart("file") MultipartFile file, @RequestPart("request") ActivityRequest request) {

        // 调用activityService的createActivity方法来创建活动
        activityService.createActivity(request, file);
        // 返回活动创建成功的响应
        return ApiResponseMe.shape(true, "活动创建成功");
    }


    /**
     * 更新活动信息和相关文件
     *
     * @param file    活动相关文件，用于更新活动的文件信息
     * @param request 活动请求对象，包含需要更新的活动详细信息
     * @return 返回操作结果，包括成功标志和提示信息
     */
    @Operation(summary = "编辑活动", description = "编辑活动")
    @PostMapping("/update")
    public ApiResponseMe updateActivity(@RequestPart("file") MultipartFile file, @RequestPart("request") ActivityRequest request) {
        // 调用活动服务的更新方法，传入活动请求和文件进行更新操作
        activityService.updateActivity(request, file);
        // 返回活动更新成功的响应
        return ApiResponseMe.shape(true, "活动更新成功");
    }


    /**
     * 删除活动
     * 该方法通过接收活动ID来删除对应的活动信息
     * 主要用于管理员或具有相应权限的用户删除不再需要或存在错误的活动记录
     *
     * @param ids 活动ID，标识要删除的活动
     * @return 返回一个包含删除结果信息的ApiResponseMe对象
     */
    @Operation(summary = "删除活动", description = "删除活动")
    @DeleteMapping("/delete")
    public ApiResponseMe deleteActivities(@RequestParam Long ids) {
        // 调用activityService的deleteActivities方法来执行实际的删除操作
        activityService.deleteActivities(ids);
        // 返回删除成功的响应信息
        return ApiResponseMe.shape(true, "活动删除成功");

    }


    /**
     * 查看报名情况
     * <p>
     * 此方法允许用户通过活动ID查看报名情况它使用GET请求获取相关信息
     *
     * @param activityId 活动ID，用于指定要查看报名情况的活动
     * @return 返回包含报名信息的响应
     */
    @Operation(summary = "查看报名情况", description = "查看报名情况")
    @GetMapping("/registration/{activityId}")
    public ApiResponseMe getRegistration(@PathVariable Long activityId) {

        // 根据活动ID获取报名情况列表
        List<ApplicantsVO> activities = activityService.getRegistration(activityId);
        // 返回成功响应，包含报名情况列表
        return ApiResponseMe.success(activities);

    }



    /**
     * 审核活动报名
     *
     * 此方法用于审核活动报名，支持批量或单个审核
     * 它接收一个包含用户ID、审核状态和活动ID的请求对象，
     * 并调用activityService进行审核操作
     *
     * @param request 包含用户ID列表、审核状态和活动ID的请求对象
     *                用于指定哪些用户的报名需要被审核，以及审核的结果
     * @return 返回一个自定义的ApiResponseMe对象，表示审核操作是否成功
     */
    @Operation(summary = "审核活动报名", description = "审核活动报名 (批量/单个)")
    @PutMapping("/reviewRegistrations")
    public ApiResponseMe reviewRegistrations(@RequestBody RegistrationReviewRequest request) {

        // 调用activityService的reviewRegistrations方法进行审核操作
        activityService.reviewRegistrations(request.getUserIds(), request.getStatus(), request.getActivityId());

        // 返回审核操作成功的响应
        return ApiResponseMe.shape(true, "审核操作成功");

    }


    /**
     * 通过GET请求获取活动申请者信息
     *
     * @param activityId 活动ID，用于指定需要获取申请者信息的活动
     * @return 返回包含活动申请者信息的ApiResponseMe对象
     */
    @GetMapping("/getApplicants")
    public ApiResponseMe getApplicants(@RequestParam Long activityId) {

        // 调用服务层方法获取活动申请者信息
        ActivityRegistrationReviewVO registrationReviewVO = activityService.getApplicants(activityId);

        // 返回成功响应，包含活动申请者信息
        return ApiResponseMe.success(registrationReviewVO);

    }



    /**
     * 获取社团用户信息
     *
     * @param clubMemberInfoDto 包含社团成员查询条件的DTO
     * @return 包含社团成员信息的响应对象
     */
    @PostMapping("/selectClubsUser")
    public ApiResponseMe getRClubsUser(@RequestBody ClubMemberInfoDto clubMemberInfoDto) {

        List<ClubMemberInfo> applicants = activityService.getClubsUser(clubMemberInfoDto);
        return ApiResponseMe.success(applicants);

    }

    /**
     * 导出社团成员信息
     *
     * @param clubMemberInfoDto 包含社团成员导出条件的DTO
     * @return 包含社团成员信息的文件资源响应实体
     */
    @Operation(summary = "导出社团成员", description = "导出社团成员为指定格式")
    @PostMapping("/export")
    public ResponseEntity<Resource> exportMembers(@RequestBody ClubMemberInfoDto clubMemberInfoDto) {
        try {
            byte[] fileContent = activityService.exportMembers(clubMemberInfoDto);
            ByteArrayResource resource = new ByteArrayResource(fileContent);

            // 设置文件名
            String fileName = "社团成员列表_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            String extension = clubMemberInfoDto.getFormat().toLowerCase();
            fileName = URLEncoder.encode(fileName + "." + extension, StandardCharsets.UTF_8.toString());

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);

            // 设置Content-Type
            MediaType mediaType;
            if (extension.equals("xlsx")) {
                mediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            } else if (extension.equals("csv")) {
                mediaType = MediaType.parseMediaType("text/csv");
            } else if (extension.equals("txt")) {
                mediaType = MediaType.TEXT_PLAIN;
            } else {
                mediaType = MediaType.APPLICATION_OCTET_STREAM;
            }

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(mediaType)
                    .body(resource);

        } catch (BusinessException e) {
            e.printStackTrace();
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(500, "导出失败：" + e.getMessage());
        }
    }

    /**
     * 导出活动报名列表
     *
     * @param request 包含活动报名列表导出条件的请求对象
     * @return 包含活动报名信息的文件资源响应实体
     */
    @Operation(summary = "导出报名列表", description = "导出指定活动的报名列表为指定格式")
    @PostMapping("/exportRegistrations")
    public ResponseEntity<Resource> exportRegistrations(@RequestBody RegistrationExportRequest request) {
        try {
            byte[] fileContent = activityService.exportRegistrations(request);
            ByteArrayResource resource = new ByteArrayResource(fileContent);

            // 设置文件名
            String fileName = "活动报名列表_" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            String extension = request.getFormat().toLowerCase();
            fileName = URLEncoder.encode(fileName + "." + extension, StandardCharsets.UTF_8.toString());

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);

            // 设置Content-Type
            MediaType mediaType;
            if (extension.equals("xlsx")) {
                mediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            } else if (extension.equals("csv")) {
                mediaType = MediaType.parseMediaType("text/csv");
            } else if (extension.equals("txt")) {
                mediaType = MediaType.TEXT_PLAIN;
            } else {
                mediaType = MediaType.APPLICATION_OCTET_STREAM;
            }

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(mediaType)
                    .body(resource);

        } catch (BusinessException e) {
            e.printStackTrace();
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(500, "导出失败：" + e.getMessage());
        }
    }

    /**
     * 处理移除成员的请求
     * 该方法通过POST请求接收JSON格式的数据，用于从活动中移除成员
     *
     * @param removeMemberDto 包含要移除成员信息的数据传输对象
     * @return 返回一个ApiResponseMe对象，包含处理结果的信息
     */
    @PostMapping("/removeMember")
    public ApiResponseMe removeMember(@RequestBody RemoveMemberDto removeMemberDto) {
        // 调用activityService的removeMember方法来执行移除成员操作
        activityService.removeMember(removeMemberDto);
        // 如果操作成功，返回成功响应
        return ApiResponseMe.shape(true, "删除成功");
    }


    /**
     * 查询社团公告
     * <p>
     * 该方法通过POST请求接收社团公告的相关参数，并返回符合条件的社团公告列表
     * 主要功能包括调用服务层方法获取公告、检查公告列表是否为空、进行分页处理以及构建返回结果
     *
     * @param clubsAnnouncementDto 包含查询社团公告所需参数的DTO对象
     * @return 包含查询结果的ApiResponseMe对象，包括公告列表和总数
     */
    @PostMapping("/selectClubsAnnouncement")
    public ApiResponseMe getCommunityAnnouncements(@RequestBody ClubsAnnouncementDto clubsAnnouncementDto) {
        // 调用服务层方法获取社团公告列表
        List<AnnouncementVO> communityAnnouncements = activityService.getCommunityAnnouncements(clubsAnnouncementDto);
        // 检查返回的公告列表是否为空
        if (communityAnnouncements == null) {
            // 如果列表为空，返回错误信息
            return ApiResponseMe.error(400, "公告列表为空");
        }
        // 创建分页信息
        PageInfo<AnnouncementVO> pageInfo = new PageInfo<>(communityAnnouncements);
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("total", pageInfo.getTotal());
        result.put("list", communityAnnouncements);
        // 返回包含分页和列表信息的成功响应
        return ApiResponseMe.success(result);
    }


    /**
     * 获取俱乐部用户ID列表
     * <p>
     * 通过俱乐部ID来查询并返回该俱乐部关联的所有用户ID
     * 此方法处理GET请求，并以JSON格式返回用户ID列表
     *
     * @param clubId 俱乐部ID，用于查询特定俱乐部的用户
     * @return 包含用户ID列表的ApiResponseMe对象，表示API的成功响应
     */
    @GetMapping("/selectClubsUserId")
    public ApiResponseMe getClubsUserId(@RequestParam Long clubId) {
        List<Long> userIds = activityService.getClubsUserId(clubId);
        return ApiResponseMe.success(userIds);
    }


    /**
     * 更新俱乐部信息的接口方法
     * 该方法处理POST请求，用于更新文学俱乐部的信息，包括上传文件和文学俱乐部数据
     *
     * @param file           文件，用于上传与俱乐部相关的图片或文档
     * @param literatureClub 文学俱乐部的详细信息，包括名称、描述等
     * @return 返回一个ApiResponseMe对象，表示更新操作的结果
     */
    @PostMapping("/updateClubInfo")
    public ApiResponseMe updateClubInfo(@RequestPart("file") MultipartFile file, @RequestPart("literatureClub") LiteratureClubDto literatureClub) {
        // 调用服务层方法更新俱乐部信息
        activityService.updateClubInfo(literatureClub, file);
        // 返回成功响应，表示更新操作成功
        return ApiResponseMe.shape(true, "更新成功");
    }


    /**
     * 创建评论
     * <p>
     * 该方法通过POST请求接收ActivityCommentDTO对象，将其作为参数传递给activityService的createComment方法
     * 用于在系统中创建一个新的评论此方法专注于处理评论的创建，而不涉及评论的检索、更新或删除
     *
     * @param commentDTO 评论数据传输对象，包含创建评论所需的信息
     * @return 返回一个ApiResponseMe对象，表示评论操作的结果
     */
    @PostMapping("/comments")
    public ApiResponseMe createComment(@RequestBody ActivityCommentDTO commentDTO) {
        activityService.createComment(commentDTO);
        return ApiResponseMe.shape(true, "评论成功");
    }


    /**
     * 根据活动ID获取评论列表
     *
     * @param activityId 活动ID
     * @return 包含评论列表的ApiResponseMe对象
     */
    @GetMapping("/comments/{activityId}")
    public ApiResponseMe getComments(@PathVariable Long activityId) {
        List<ActivityCommentVO> comments = activityService.getComments(activityId);
        return ApiResponseMe.success(comments);
    }

    /**
     * 获取消息列表可以根据阅读状态筛选
     *
     * @param adminId    管理员ID
     * @param readStatus 阅读状态，可选参数
     * @return 包含消息列表的ApiResponseMe对象
     */
    @GetMapping("/messages")
    public ApiResponseMe getMessages(@RequestParam Long adminId, @RequestParam(required = false) Integer readStatus) {
        List<MessageVO> messages = activityService.getMessages(adminId, readStatus);
        return ApiResponseMe.success(messages);
    }

    /**
     * 更新消息阅读状态
     *
     * @param updateMessageReadStatusDto 包含消息ID和新阅读状态的DTO
     * @return 表示操作是否成功的ApiResponseMe对象
     */
    @PostMapping("/updateMessageReadStatus")
    public ApiResponseMe updateMessageReadStatus(@RequestBody UpdateMessageReadStatusDto updateMessageReadStatusDto) {
        activityService.updateMessageReadStatus(updateMessageReadStatusDto);
        return ApiResponseMe.shape(true, "修改成功");
    }

    /**
     * 获取公告阅读统计信息
     *
     * @param announcementReadCountsDto 包含公告ID和阅读状态的DTO
     * @return 包含公告阅读统计信息的MessageSummaryVO对象
     */
    @PostMapping("/getAnnouncementReadCounts")
    public ApiResponseMe getAnnouncementReadCounts(@RequestBody AnnouncementReadCountsDto announcementReadCountsDto) {
        MessageSummaryVO messageSummaryVO = activityService.getAnnouncementReadCounts(announcementReadCountsDto);
        return ApiResponseMe.success(messageSummaryVO);
    }

    /**
     * 更新个人资料，支持文件上传
     *
     * @param updatePersonalInfoRequestDto 包含个人资料信息的DTO
     * @param file                         要上传的文件，可选参数
     * @return 包含更新后的用户信息的UserVo对象
     */
    @PostMapping("/updatePersonalInfo")
    public ApiResponseMe updatePersonalInfo(@RequestPart("updatePersonalInfoRequestDto") UpdatePersonalInfoRequestDto updatePersonalInfoRequestDto, @RequestPart(name = "file", required = false) MultipartFile file) {
        UserVo userVo = activityService.updatePersonalInfo(updatePersonalInfoRequestDto, file);
        return ApiResponseMe.success(userVo);
    }
}
